package com.syx.migration.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.syx.migration.domain.*;
import com.syx.migration.mapper.*;
import com.syx.migration.mapper.old.OldJournalMapper;
import com.syx.migration.service.IJournalModuleService;
import com.syx.migration.service.MgnLinkIdService;
import com.syx.migration.utils.BaseUtils;
import com.syx.migration.utils.BeanMapUtils;
import com.syx.migration.utils.TimeIdWorker;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class JournalModuleServiceImpl implements IJournalModuleService {

    private final MgnLinkIdService mgnLinkIdService;

    private final SyxJournalMapper journalMapper;
    private final MgnLinkIdMapper mgnLinkIdMapper;
    private final OldJournalMapper oldJournalMapper;
    private final SyxJournalBorrowMapper journalBorrowMapper;
    private final SyxJournalCatalogMapper journalCatalogMapper;
    private final SyxJournalEnterLogMapper journalEnterLogMapper;
    private final SyxJournalCirculateLogMapper journalCirculateLogMapper;

    private final SyxReaderMapper readerMapper;
    private final SysDeptMapper deptMapper;

    @Override
    @DSTransactional
    public void migrateCatalogue() {
        String tbName = "syx_journal_catalog";
        ArrayList<MgnLinkId> mgnLinkIds = new ArrayList<>();
        Map<String, String> schoolMap = mgnLinkIdService.getMapByTbName("syx_school");
        List<SyxJournalCatalog> syxJournalCatalogs = BeanMapUtils.mapListToBeanList(oldJournalMapper.queryCatalogue(), SyxJournalCatalog.class);
        syxJournalCatalogs.forEach(item -> {
            String newId = TimeIdWorker.createId(item.getCreateTime());
            item.setId(BaseUtils.str2Long(newId));
            String tenantId = schoolMap.get(item.getBelong());
            item.setTenantId(tenantId);
            mgnLinkIds.add(new MgnLinkId(newId, item.getOldId(), tbName));
        });
        journalCatalogMapper.insertBatch(syxJournalCatalogs);
        mgnLinkIdMapper.delete(new LambdaQueryWrapper<MgnLinkId>().eq(MgnLinkId::getTableName, tbName));
        mgnLinkIdMapper.insertBatch(mgnLinkIds);
    }

    @Override
    @DSTransactional
    public void migrateInfo() {
        String tbName = "syx_journal";
        ArrayList<MgnLinkId> mgnLinkIds = new ArrayList<>();
        Map<String, String> schoolMap = mgnLinkIdService.getMapByTbName("syx_school");
        Map<String, String> journalCatalogMap = mgnLinkIdService.getMapByTbName("syx_journal_catalog");
        Map<String, String> libraryRoomMap = mgnLinkIdService.getMapByTbName("syx_library_room");
        Map<String, String> libraryBookselfMap = mgnLinkIdService.getMapByTbName("syx_library_bookself");
        Map<String, String> readerMap = mgnLinkIdService.getMapByTbName("syx_reader");
        List<Map<String, Object>> journalList = oldJournalMapper.queryJournal();
        journalList.forEach(item ->{
            String newId = TimeIdWorker.createId(item.get("createTime").toString());
            item.put("id", newId);
            mgnLinkIds.add(new MgnLinkId(newId, item.get("oldId").toString(), tbName));
            String tenantId = schoolMap.get(item.get("belong").toString());
            item.put("tenantId", tenantId);
            String catalogId = journalCatalogMap.get(item.get("catalogId").toString());
            item.put("catalogId", catalogId);
            String roomId = libraryRoomMap.get(item.get("roomId").toString());
            item.put("roomId", roomId);
            String libraryBookselfId = libraryBookselfMap.get(item.get("libraryBookselfId").toString());
            item.put("libraryBookselfId", libraryBookselfId);
            String bookselfFace = "1".equals(item.get("bookselfFace")) ? "A" : "B";
            item.put("bookselfFace", bookselfFace);
            if(Objects.nonNull(item.get("createBy"))){
                String readerId = readerMap.get(item.get("createBy").toString());
                item.put("createBy", readerId);
            }
        });
        List<SyxJournal> syxJournals = BeanMapUtils.mapListToBeanList(journalList, SyxJournal.class);
        journalMapper.insertBatch(syxJournals);
        mgnLinkIdMapper.delete(new LambdaQueryWrapper<MgnLinkId>().eq(MgnLinkId::getTableName, tbName));
        mgnLinkIdMapper.insertBatch(mgnLinkIds);
    }

    @Override
    @DSTransactional
    public void migrateBorrow() {
        String tbName = "syx_journal_borrow";
        ArrayList<MgnLinkId> mgnLinkIds = new ArrayList<>();
        Map<String, String> schoolMap = mgnLinkIdService.getMapByTbName("syx_school");
        Map<String, String> readerMap = mgnLinkIdService.getMapByTbName("syx_reader");
        Map<String, String> journalMap = mgnLinkIdService.getMapByTbName("syx_journal");
        List<Map<String, Object>> borrowList = oldJournalMapper.queryBorrow();
        borrowList.forEach(item->{
            String newId = TimeIdWorker.createId(item.get("createTime").toString());
            item.put("id", newId);
            mgnLinkIds.add(new MgnLinkId(newId, item.get("oldId").toString(), tbName));
            String tenantId = schoolMap.get(item.get("belong").toString());
            item.put("tenantId", tenantId);
            if(Objects.nonNull(item.get("journalId"))){
                String journalId = journalMap.get(item.get("journalId").toString());
                item.put("journalId", journalId);
            }
            if(Objects.nonNull(item.get("readerId"))){
                String readerId = readerMap.get(item.get("readerId").toString());
                item.put("readerId", readerId);
            }
            item.put("borrowType", 0);
            item.put("backStatus", "借出".equals(item.get("backStatus").toString())?'0':'1');
            item.put("operatorType", '0');
            item.put("autoBack", '1');
        });
        List<SyxJournalBorrow> journalBorrows = BeanMapUtils.mapListToBeanList(borrowList, SyxJournalBorrow.class);
        journalBorrowMapper.insertBatch(journalBorrows);
        mgnLinkIdMapper.delete(new LambdaQueryWrapper<MgnLinkId>().eq(MgnLinkId::getTableName, tbName));
        mgnLinkIdMapper.insertBatch(mgnLinkIds);
    }

    @Override
    @DSTransactional
    public void migrateReader() {
        List<SyxJournalBorrow> journalBorrows = journalBorrowMapper.selectList(new LambdaQueryWrapper<>());
        List<SyxReader> syxReaders = readerMapper.selectList(new LambdaQueryWrapper<>());
        Map<Long, List<SyxJournalBorrow>> journalBorrowMaps = journalBorrows.stream().collect(Collectors.groupingBy(SyxJournalBorrow::getReaderId));
        syxReaders.forEach(item->{
            if(journalBorrowMaps.containsKey(item.getReaderId())){
                // 历史借阅次数
                int historyJournalNum = journalBorrowMaps.get(item.getReaderId()).size();
                // 在借次数
                int borrowJournalNum = journalBorrowMaps.get(item.getReaderId()).stream().filter(file -> "0".equals(file.getBackStatus())).toList().size();
                item.setHistoryJournalNum(historyJournalNum);
                item.setBorrowJournalNum(borrowJournalNum);
                readerMapper.updateById(item);
            }
        });
    }

    @Override
    @DSTransactional
    public void migrateCatalogNum() {
        List<SyxJournalCatalog> journalCatalogs = journalCatalogMapper.selectList(new LambdaQueryWrapper<>());
        List<SyxJournal> journals = journalMapper.selectList(new LambdaQueryWrapper<>());
        Map<Long, List<SyxJournal>> journalMap = journals.stream().collect(Collectors.groupingBy(SyxJournal::getCatalogId));
        journalCatalogs.forEach(item->{
            if (journalMap.containsKey(item.getId())){
                int size = journalMap.get(item.getId()).size();
                item.setJournalNum(size);
                journalCatalogMapper.updateById(item);
            }
        });
    }

    @Override
    @DSTransactional
    public void migrateBorrowNum() {
        List<SyxJournal> journals = journalMapper.selectList(new LambdaQueryWrapper<>());
        List<SyxJournalBorrow> journalBorrows = journalBorrowMapper.selectList(new LambdaQueryWrapper<>());
        Map<Long, List<SyxJournalBorrow>> journalBorrowMap = journalBorrows.stream().collect(Collectors.groupingBy(SyxJournalBorrow::getJournalId));
        journals.forEach(item->{
            if (journalBorrowMap.containsKey(item.getId())){
                int size = journalBorrowMap.get(item.getId()).size();
                item.setBorrowNum(size);
                journalMapper.updateById(item);
            }
        });
    }

    @Override
    @DSTransactional
    public void migrateEnter() {
        journalEnterLogMapper.delete(new LambdaQueryWrapper<>());
        ArrayList<SyxJournalEnterLog> journalEnterLogLists = new ArrayList<>();
        List<SyxJournal> syxJournals = journalMapper.selectList(new LambdaQueryWrapper<>());
        Map<Long, List<SyxJournalCatalog>> journalCatalogMaps = journalCatalogMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.groupingBy(SyxJournalCatalog::getId));
        Map<Long, List<SyxReader>> readerMaps = readerMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.groupingBy(SyxReader::getReaderId));

        syxJournals.forEach(item->{
            SyxJournalEnterLog journalEnterLog = new SyxJournalEnterLog();
            journalEnterLog.setTenantId(item.getTenantId());
            if(readerMaps.containsKey(item.getCreateBy())){
                SyxReader syxReader = readerMaps.get(item.getCreateBy()).get(0);
                journalEnterLog.setUserName(syxReader.getName());
                journalEnterLog.setDeptId(syxReader.getDeptId());
            }
            if(journalCatalogMaps.containsKey(item.getCatalogId())){
                journalEnterLog.setIssueNumber(journalCatalogMaps.get(item.getCatalogId()).get(0).getIssueNumber());
            }
            journalEnterLog.setJournalNumber(item.getJournalNumber());
            journalEnterLog.setBracketId(item.getBracketId());
            journalEnterLog.setRoomId(item.getRoomId());
            journalEnterLog.setBookInfo(new JSONObject(item).toString());
//            journalEnterLog.setCreateBy(item.getCreateBy());
            journalEnterLog.setCreateTime(item.getCreateTime());
//            journalEnterLog.setUpdateBy(item.getUpdateBy());
            journalEnterLog.setUpdateTime(item.getUpdateTime());
            journalEnterLogLists.add(journalEnterLog);
        });
        journalEnterLogMapper.insertBatch(journalEnterLogLists);
    }

    @Override
    @DSTransactional
    public void migrateCirculate() {
        journalCirculateLogMapper.delete(new LambdaQueryWrapper<>());
        ArrayList<SyxJournalCirculateLog> journalCirculateLogList = new ArrayList<>();
        // 借阅信息
        List<SyxJournalBorrow> journalBorrows = journalBorrowMapper.selectList(new LambdaQueryWrapper<>());
        // 读者信息
        Map<Long, List<SyxReader>> readerMaps = readerMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.groupingBy(SyxReader::getReaderId));
        // 部门信息
        Map<Long, List<SysDept>> deptMaps = deptMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.groupingBy(SysDept::getDeptId));
        // 期刊信息
        Map<Long, List<SyxJournal>> journalMaps = journalMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.groupingBy(SyxJournal::getId));
        //编目信息
        Map<Long, List<SyxJournalCatalog>> journalCatalogMaps = journalCatalogMapper.selectList(new LambdaQueryWrapper<>())
                .stream().collect(Collectors.groupingBy(SyxJournalCatalog::getId));
        journalBorrows.forEach(item->{
            SyxJournalCirculateLog journalCirculateLog = new SyxJournalCirculateLog();
            BeanUtil.copyProperties(item, journalCirculateLog);
            journalCirculateLog.setTenantId(item.getTenantId());
            journalCirculateLog.setBorrowId(item.getId());
            // 读者信息,读者编号,部门ID, 部门名称
            if(readerMaps.containsKey(item.getReaderId())){
                SyxReader reader = readerMaps.get(item.getReaderId()).get(0);
                journalCirculateLog.setReaderInfo(new JSONObject(reader).toString());
                journalCirculateLog.setBorrowCard(reader.getBorrowCard());
                journalCirculateLog.setDeptId(reader.getDeptId());
                if(deptMaps.containsKey(reader.getDeptId())){
                    journalCirculateLog.setDeptName(deptMaps.get(reader.getDeptId()).get(0).getDeptName());
                }
            }
            // 期刊信息,期刊编号,编目信息
            if(journalMaps.containsKey(item.getJournalId())){
                SyxJournal journal = journalMaps.get(item.getJournalId()).get(0);
                journalCirculateLog.setJournalInfo(new JSONObject(journal).toString());
                journalCirculateLog.setJournalNumber(journal.getJournalNumber());
                if (journalCatalogMaps.containsKey(journal.getCatalogId())){
                    SyxJournalCatalog journalCatalog = journalCatalogMaps.get(journal.getCatalogId()).get(0);
                    journalCirculateLog.setCatalogInfo(new JSONObject(journalCatalog).toString());
                }
            }
            journalCirculateLog.setBorrowStatus(item.getBackStatus());
            if(Objects.nonNull(item.getResidueDay())){
                journalCirculateLog.setIsOverdue(item.getResidueDay()<0?"0":"1");
            }
            journalCirculateLogList.add(journalCirculateLog);
        });
        journalCirculateLogMapper.insertBatch(journalCirculateLogList);
    }

}
